﻿using System.Collections.Generic;
using System.Linq;
using Mbs.ComponentModel.Container;
using Mbs.ComponentModel.Container.Injection;
using Mbs.ComponentModel.Container.Loader;
using NUnit.Framework;

namespace Mbs.Test.IoC
{
    [TestFixture]
    public class XmlConfigTest:TestBase
    {

        protected override void Init()
        {
            kernel.LoaderManager.Register(new XmlLoader("IoC.xml"));
        }
        

        [Test]
        public void RegisterTest()
        {
               Assert.IsTrue(kernel.HasRegister<IPerson>());
        }

        [Test]
        public void GetByIdTest()
        {

            var person = kernel.Get<IPerson>("person");
            Assert.IsTrue(person != null);

            var person2 = kernel.Get<Person>("person");
            Assert.IsTrue(person2 != null);

            Assert.AreSame(person, person2);
            Assert.IsTrue(Person.HasVisited);
        }

        [Test]
        public void GetByTypeTest()
        {
         
            var person = kernel.Get<IPerson>();
            Assert.IsTrue(person != null);

            var person2 = kernel.Get<IPerson, Person>();
            Assert.IsTrue(person2 != null);

            Assert.AreSame(person, person2);
            Assert.IsTrue(Person.HasVisited);
        }

        [Test]
        public void GetAllTest()
        {
            var person = kernel.Get<IPerson>();
            Assert.IsTrue(person != null);
            Assert.IsTrue(typeof(IPerson).IsAssignableFrom(person.GetType()));

            var items = kernel.GetAll<IPerson>().ToArray();
            Assert.IsTrue(items[0] is Person);
            Assert.IsTrue(items[1] is Person2);

        }

        [Test]
        public void TransientLifestyleTest()
        {

            var person = kernel.Get<IPerson>("TransientPerson");
            Assert.IsTrue(person != null);

            var person2 = kernel.Get<IPerson>("TransientPerson") as Person;
            Assert.IsTrue(person2 != null);

            Assert.AreNotSame(person, person2);
            Assert.IsTrue(Person.HasVisited);
        }

        [Test]
        public void LazyInitTest()
        {
            Assert.IsTrue(Person.HasVisited);

        }

        [Test]
        public void StartableListnerTest()
        {
            var person = kernel.Get<StartablePerson>("StartablePerson");
            Assert.IsTrue(person != null);
            Assert.IsTrue(person.HasStarted);
            Assert.IsFalse(person.HasStopped);
        }


        [Test]
        public void ConstructorInjectTest()
        {
            var person = kernel.Get<Person2>("Person2");
            Assert.IsTrue(person != null);
            Assert.IsNotNull(person.Horse);
        }

        [Test]
        public void ConstructorInject2Test()
        {

            kernel.RegisterInstance("str", typeof(string), "ZhangSan");

            var person = kernel.Get<Person5>("person5");
            Assert.IsTrue(person != null);
            Assert.IsNotNull(person.Horse);
            Assert.IsNotNull(person.A);
            Assert.IsTrue(person.HasVisited);
            Assert.IsTrue(string.IsNullOrEmpty(person.Name));
        }


        [Test]
        public void ConstructorInject3Test()
        {

            kernel.RegisterInstance("str", typeof(string), "ZhangSan");

            var person = kernel.Get<Person6>("person6");
            Assert.IsTrue(person != null);
            Assert.IsNotNull(person.Horse);
            Assert.IsNotNull(person.A);
            Assert.IsTrue(person.HasVisited);
            Assert.AreEqual("ZhangSan", person.Name);
        }

        [Test]
        public void AutoConstructorTest()
        {
            var person = kernel.Get<Person2>("Person2");
            Assert.IsTrue(person != null);
            Assert.IsNotNull(person.Horse);
        }

        [Test]
        public void GenericTest()
        {
            kernel.InjectStrategyManager.Register(new AutoPropertyInjectStragegy());

           
            Assert.IsTrue(kernel.HasRegister(typeof(IList<>)));
            Assert.IsTrue(kernel.HasRegister(typeof(IList<int>)));
            Assert.IsTrue(kernel.HasRegister(typeof(IList<string>)));

            Assert.IsTrue(kernel.HasRegister(typeof(GenericCollection<>)));
            Assert.IsTrue(kernel.HasRegister(typeof(GenericCollection<int>)));
            Assert.IsTrue(kernel.HasRegister(typeof(GenericCollection<string>)));

            var coll = kernel.Get<GenericCollection<int>>();
            Assert.IsNotNull(coll);
            Assert.IsNotNull(coll.Items);

            var instance = kernel.Get<IList<int>>();
            Assert.IsNotNull(instance);
            Assert.AreSame(coll.Items, instance);

            var instance2 = kernel.Get<IList<int>>();
            Assert.IsNotNull(instance2);
            Assert.AreSame(coll.Items, instance2);


            var coll2 = kernel.Get<GenericCollection<string>>();
            var instance3 = kernel.Get<IList<string>>();
            Assert.IsNotNull(instance3);
            Assert.AreSame(coll2.Items, instance3);

            var instance4 = kernel.Get<IList<string>>();
            Assert.IsNotNull(instance4);
            Assert.AreSame(coll2.Items, instance4);


        }

    }
}
